package code16_thread;

public class Test06 {

	public static void main(String[] args) {
		// 锁对象
		Object obj = new Object();
		Waiter w1 = new Waiter();
		w1.obj = obj;// 设置锁对象
		w1.start();
		
		Waiter w2 = new Waiter();
		w2.obj = obj;// 设置锁对象
		w2.start();
		
		try {
			// 确保 先 wait, 再唤醒
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		Notifyer n1 = new Notifyer();
		n1.obj = obj;// 设置锁对象
		n1.start();
	}
	
}

class Waiter extends Thread {
	public Object obj;
	public void run() {
		synchronized (obj) {
			try {
				// 等待指定的时间, 之后会自动唤醒
				//this.wait(1000);
				// 无限期等待, 直到被唤醒
				System.out.println(getName()+" Waiter.run() 等待");
				obj.wait();
				System.out.println(getName()+" Waiter.run() 被唤醒了");
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println(getName()+" Waiter.run() 被中断了");
			}
		}
		System.out.println(getName()+" Waiter.finish");
	}
}

class Notifyer extends Thread {
	public Object obj;
	public void run() {
		synchronized (obj) {
			// 是正常唤醒, 不会触发异常
			obj.notify();// 随机唤醒一个 当前锁对象的等待池中 线程
			//obj.notifyAll();// 唤醒 当前锁对象的等待池中 的所有线程
			System.out.println("Notifyer.run() 执行了唤醒");
		}
	}
}
